home *** CD-ROM | disk | FTP | other *** search
/ Symantec Visual Cafe for Java 2.5 / symantec-visual-cafe-2.5-database-dev-edition.iso / Visual Cafe Pro v1.0 / TUTORIAL.BIN / BasicCell.class (.txt) < prev    next >
Encoding:
Java Class File  |  1997-01-30  |  13.6 KB  |  627 lines

  1. package symantec.itools.db.awt;
  2.  
  3. import java.awt.Event;
  4. import java.awt.FontMetrics;
  5. import java.awt.Graphics;
  6. import java.awt.Image;
  7. import java.awt.Rectangle;
  8. import java.awt.image.ImageObserver;
  9.  
  10. public class BasicCell implements TableCell, ImageObserver {
  11.    Grid view;
  12.    DataSource dataSource;
  13.    Coordinate coords;
  14.    boolean selected;
  15.    boolean keyPressedYet;
  16.    boolean loseFocusOnArrow;
  17.    int cursorPos;
  18.    int hlFirst;
  19.    int hlLast;
  20.    boolean selectionMade;
  21.    int offset;
  22.    int chopIndex;
  23.    int toLeftOfCell;
  24.    int startX;
  25.    boolean defaultCell;
  26.    int type;
  27.    static final int PADSIDES = 5;
  28.  
  29.    public BasicCell(Grid tv, DataSource ds) {
  30.       this.view = tv;
  31.       this.dataSource = ds;
  32.    }
  33.  
  34.    public TableCell cloneCell() {
  35.       BasicCell bs = new BasicCell(this.view, this.dataSource);
  36.       if (this.coords != null) {
  37.          bs.coords = new Coordinate(this.coords.row, this.coords.col);
  38.       }
  39.  
  40.       bs.selected = this.selected;
  41.       bs.keyPressedYet = this.keyPressedYet;
  42.       bs.loseFocusOnArrow = this.loseFocusOnArrow;
  43.       bs.cursorPos = this.cursorPos;
  44.       bs.selectionMade = this.selectionMade;
  45.       bs.offset = this.offset;
  46.       bs.type = this.type;
  47.       return bs;
  48.    }
  49.  
  50.    public int type() {
  51.       return this.type;
  52.    }
  53.  
  54.    public int type(int t) {
  55.       if (t <= 3 && t >= 0) {
  56.          return this.type = t;
  57.       } else {
  58.          throw new IllegalArgumentException("Invalid cell type");
  59.       }
  60.    }
  61.  
  62.    public void setGrid(Grid v, DataSource ds) {
  63.       this.view = v;
  64.       this.dataSource = ds;
  65.    }
  66.  
  67.    public void setDefaultFlag() {
  68.       this.defaultCell = true;
  69.    }
  70.  
  71.    public void reset() {
  72.       this.selected = false;
  73.       this.keyPressedYet = false;
  74.       this.loseFocusOnArrow = false;
  75.       this.cursorPos = 0;
  76.       this.selectionMade = false;
  77.       this.offset = 0;
  78.    }
  79.  
  80.    public boolean isCellTypeEditable() {
  81.       return true;
  82.    }
  83.  
  84.    public void setCoordinates(Coordinate c) {
  85.       this.coords = c;
  86.    }
  87.  
  88.    public Coordinate getCoordinates() {
  89.       return this.coords;
  90.    }
  91.  
  92.    public int row() {
  93.       return this.coords.row;
  94.    }
  95.  
  96.    public void setRow(int r) {
  97.       this.coords.row = r;
  98.    }
  99.  
  100.    public int col() {
  101.       return this.coords.col;
  102.    }
  103.  
  104.    public void setCol(int c) {
  105.       this.coords.col = c;
  106.    }
  107.  
  108.    public boolean mouseEvent(Event e) {
  109.       try {
  110.          switch (e.id) {
  111.             case 63:
  112.                this.keyPressedYet = false;
  113.                this.view.redraw(true);
  114.                this.offset = 0;
  115.                this.view.generateEvent(e, 63, this);
  116.                break;
  117.             case 501:
  118.                if (!e.shiftDown()) {
  119.                   this.keyPressedYet = true;
  120.                   this.view.setCapture();
  121.                   this.cursorPos = this.findCursorPos(e.x);
  122.                   this.selectionMade = false;
  123.                } else {
  124.                   this.hlFirst = this.cursorPos;
  125.                   this.hlLast = this.findCursorPos(e.x);
  126.                   this.selectionMade = true;
  127.                }
  128.  
  129.                this.view.redrawCell(this);
  130.                this.view.generateEvent(e, 61, this);
  131.                break;
  132.             case 502:
  133.                this.view.generateEvent(e, 60, this);
  134.                break;
  135.             case 506:
  136.                if (!this.selectionMade && this.findCursorPos(e.x) != this.cursorPos) {
  137.                   this.hlFirst = this.cursorPos;
  138.                   this.selectionMade = true;
  139.                }
  140.  
  141.                this.hlLast = this.cursorPos = this.findCursorPos(e.x);
  142.                this.view.redrawCell(this);
  143.                this.view.generateEvent(e, 62, this);
  144.          }
  145.       } catch (DataNotAvailable ex) {
  146.          this.view.handleException(this.row(), this.col(), ex);
  147.       }
  148.  
  149.       return true;
  150.    }
  151.  
  152.    int findCursorPos(int x) throws DataNotAvailable {
  153.       if (x < -this.offset) {
  154.          return 0;
  155.       } else {
  156.          int total = this.offset + x;
  157.          FontMetrics fm = this.view.getCellFontMetrics(this);
  158.          Data data = this.readData();
  159.          String text = data.toString();
  160.          int len = text.length();
  161.          Image im = data.toImage();
  162.          int align = this.view.getCellAlignment(this);
  163.          if (align == 0) {
  164.             if (this.offset == 0) {
  165.                total -= 7;
  166.                if (im != null) {
  167.                   int imageOffset = im.getWidth(this) + 2;
  168.                   int w = this.view.getColumnWidth(this.getCoordinates().col);
  169.                   int sw = fm.stringWidth(text);
  170.                   if (imageOffset + sw + 2 + 5 <= w) {
  171.                      total -= imageOffset;
  172.                   }
  173.                }
  174.             }
  175.          } else if (align == 2) {
  176.             int sw = fm.stringWidth(text);
  177.             int w = this.view.getColumnWidth(this.getCoordinates().col);
  178.             if (sw <= w - 10) {
  179.                total = total - w + sw + 5;
  180.             }
  181.          } else if (align == 1) {
  182.             int sw = fm.stringWidth(text);
  183.             int w = this.view.getColumnWidth(this.getCoordinates().col);
  184.             if (sw <= w) {
  185.                total -= (w - sw) / 2;
  186.             }
  187.          }
  188.  
  189.          if (total <= 0) {
  190.             return 0;
  191.          } else {
  192.             for(int i = 1; i <= len; ++i) {
  193.                if (fm.stringWidth(text.substring(0, i - 1) + fm.charWidth(text.charAt(i - 1)) / 2) > total) {
  194.                   return i;
  195.                }
  196.             }
  197.  
  198.             return len;
  199.          }
  200.       }
  201.    }
  202.  
  203.    public CellHints getHints() {
  204.       return this.view.getHintsForCell(this, this.coords.row, this.coords.col);
  205.    }
  206.  
  207.    public Data getData() throws DataNotAvailable {
  208.       return this.dataSource.getData(this.coords);
  209.    }
  210.  
  211.    public Data readData() throws DataNotAvailable {
  212.       return this.dataSource.readData(this.coords.row, this.coords.col);
  213.    }
  214.  
  215.    void deleteChar(Data data) {
  216.       if (this.cursorPos != 0) {
  217.          data.deleteChar(this.cursorPos);
  218.          --this.cursorPos;
  219.       }
  220.    }
  221.  
  222.    void deleteSelection(Data data) {
  223.       int hlLeft = Math.min(this.hlFirst, this.hlLast);
  224.       int hlRight = Math.max(this.hlFirst, this.hlLast);
  225.  
  226.       for(int i = hlLeft; i < hlRight; ++i) {
  227.          data.deleteChar(hlLeft + 1);
  228.       }
  229.  
  230.       this.cursorPos = hlLeft;
  231.    }
  232.  
  233.    public boolean keyEvent(Event e) {
  234.       Data data;
  235.       try {
  236.          data = this.getData();
  237.       } catch (DataNotAvailable ex) {
  238.          this.view.handleException(this.row(), this.col(), ex);
  239.          return true;
  240.       }
  241.  
  242.       char c = (char)e.key;
  243.       boolean changed = false;
  244.       boolean handled = false;
  245.       boolean editable = data.isEditable(this.coords.row, this.coords.col) || this.getHints().editable();
  246.       if (editable || e.id != 403 && e.id != 401) {
  247.          if (!editable && e.id == 402) {
  248.             return this.view.generateEvent(e, 59, this);
  249.          } else if (e.id == 403) {
  250.             if (e.shiftDown() && !this.selectionMade) {
  251.                this.selectionMade = true;
  252.                this.hlFirst = this.hlLast = this.cursorPos;
  253.             } else if (!e.shiftDown()) {
  254.                this.selectionMade = false;
  255.             }
  256.  
  257.             switch (c) {
  258.                case '╧¿':
  259.                case '╧¼':
  260.                   if (this.cursorPos != 0) {
  261.                      this.cursorPos = 0;
  262.                      changed = true;
  263.                   }
  264.                   break;
  265.                case '╧⌐':
  266.                case '╧¡':
  267.                   int len = data.toString().length();
  268.                   if (this.cursorPos != len) {
  269.                      this.cursorPos = len;
  270.                      changed = true;
  271.                   }
  272.                case '╧¬':
  273.                case '╧½':
  274.                default:
  275.                   break;
  276.                case '╧«':
  277.                   if (this.cursorPos > 0) {
  278.                      --this.cursorPos;
  279.                      changed = true;
  280.                   }
  281.                   break;
  282.                case '╧»':
  283.                   if (this.cursorPos < data.toString().length()) {
  284.                      ++this.cursorPos;
  285.                      changed = true;
  286.                   }
  287.             }
  288.  
  289.             if (this.selectionMade) {
  290.                this.hlLast = this.cursorPos;
  291.             }
  292.  
  293.             if (changed) {
  294.                this.view.redrawCell(this);
  295.             }
  296.  
  297.             return this.view.generateEvent(e, 58, this);
  298.          } else {
  299.             if (e.id == 401) {
  300.                if (!this.keyPressedYet) {
  301.                   if (e.key < 33 || e.key > 122) {
  302.                      return this.view.generateEvent(e, 58, this);
  303.                   }
  304.  
  305.                   data.clearText();
  306.                   data.appendChar(c);
  307.                   this.keyPressedYet = true;
  308.                   this.view.setCapture();
  309.                   this.cursorPos = 1;
  310.                   if (this.defaultCell) {
  311.                      this.view.addCellFromDefault(this);
  312.                   }
  313.                } else {
  314.                   if (this.selectionMade) {
  315.                      this.deleteSelection(data);
  316.                      this.selectionMade = false;
  317.                      if (c == '\b' || c == 127) {
  318.                         return this.view.generateEvent(e, 58, this);
  319.                      }
  320.                   }
  321.  
  322.                   if (e.key == 27) {
  323.                      this.cursorPos = 0;
  324.                      this.keyPressedYet = false;
  325.                      handled = this.view.generateEvent(e, 54, this);
  326.                   } else if (c == '\b') {
  327.                      this.deleteChar(data);
  328.                      handled = this.view.generateEvent(e, 57, this);
  329.                   } else if (c == 127) {
  330.                      if (this.cursorPos != data.toString().length()) {
  331.                         ++this.cursorPos;
  332.                         this.deleteChar(data);
  333.                         handled = this.view.generateEvent(e, 57, this);
  334.                      }
  335.                   } else if (this.cursorPos == data.toString().length()) {
  336.                      data.appendChar(c);
  337.                      ++this.cursorPos;
  338.                      if (this.defaultCell) {
  339.                         this.view.addCellFromDefault(this);
  340.                      }
  341.  
  342.                      handled = this.view.generateEvent(e, 57, this);
  343.                   } else {
  344.                      data.insertChar(this.cursorPos, c);
  345.                      ++this.cursorPos;
  346.                      if (this.defaultCell) {
  347.                         this.view.addCellFromDefault(this);
  348.                      }
  349.                   }
  350.                }
  351.  
  352.                this.view.redrawCell(this);
  353.                handled |= this.view.generateEvent(e, 58, this);
  354.             } else if (e.id == 402) {
  355.                this.view.generateEvent(e, 59, this);
  356.             }
  357.  
  358.             return handled;
  359.          }
  360.       } else {
  361.          return this.view.generateEvent(e, 58, this);
  362.       }
  363.    }
  364.  
  365.    public boolean loseFocusOnArrow() {
  366.       return this.selected & !this.keyPressedYet;
  367.    }
  368.  
  369.    public void activateCursor() {
  370.       this.selected = true;
  371.       this.view.redrawCell(this);
  372.    }
  373.  
  374.    public void deactivateCursor() {
  375.       this.selected = false;
  376.       this.view.redrawCell(this);
  377.    }
  378.  
  379.    public boolean canLoseFocus() {
  380.       try {
  381.          this.dataSource.commitData();
  382.          return true;
  383.       } catch (Exception ex) {
  384.          this.view.handleException(this.row(), this.col(), ex);
  385.          return false;
  386.       }
  387.    }
  388.  
  389.    public boolean focusEvent(Event e) {
  390.       if (e.id == 1004) {
  391.          this.selected = true;
  392.          this.view.generateEvent(e, 55, this);
  393.          this.view.redrawCell(this);
  394.       } else {
  395.          this.selected = false;
  396.          this.keyPressedYet = false;
  397.          this.selectionMade = false;
  398.          this.offset = 0;
  399.          this.cursorPos = 0;
  400.          this.view.generateEvent(e, 56, this);
  401.  
  402.          try {
  403.             this.dataSource.commitData();
  404.          } catch (Exception ex) {
  405.             this.view.handleException(this.row(), this.col(), ex);
  406.          }
  407.  
  408.          this.view.redrawAroundCell(this);
  409.       }
  410.  
  411.       return true;
  412.    }
  413.  
  414.    public boolean actionEvent(Event e) {
  415.       this.keyPressedYet = false;
  416.       this.view.redraw(true);
  417.       this.offset = 0;
  418.       return true;
  419.    }
  420.  
  421.    public void drawCell(Graphics g, CellHints hints) {
  422.       Data data;
  423.       try {
  424.          data = this.readData();
  425.       } catch (DataNotAvailable ex) {
  426.          this.view.handleException(this.row(), this.col(), ex);
  427.          data = new ImageStringData(this.dataSource, "");
  428.       }
  429.  
  430.       Rectangle r = hints.bounds();
  431.       FontMetrics fm = this.view.getCellFontMetrics(this);
  432.       fm.getAscent();
  433.       int sw = fm.stringWidth(data.toString());
  434.       int imageOffset = 0;
  435.       int origX = r.x;
  436.       int origWidth = r.width;
  437.       hints.setBackground(g);
  438.       g.fillRect(r.x, r.y, r.width - 1, r.height - 1);
  439.       Image im = data.toImage();
  440.       switch (hints.alignment()) {
  441.          case 0:
  442.             if (im != null) {
  443.                imageOffset = im.getWidth(this) + 2;
  444.             }
  445.  
  446.             if (imageOffset + sw + 2 + 5 <= r.width && im != null) {
  447.                r.x += 5;
  448.                ++r.y;
  449.                g.drawImage(im, r.x, r.y, this);
  450.                --r.y;
  451.             } else {
  452.                imageOffset = 0;
  453.             }
  454.  
  455.             r.x = origX + imageOffset + 5;
  456.             break;
  457.          case 1:
  458.             if (sw > r.width - 10) {
  459.                r.x += 5;
  460.             } else {
  461.                r.x += (r.width - sw) / 2;
  462.             }
  463.             break;
  464.          case 2:
  465.             if (im != null) {
  466.                imageOffset = im.getWidth(this);
  467.             }
  468.  
  469.             if (imageOffset + 2 + sw + 10 + 3 <= r.width && im != null) {
  470.                r.x = r.x + r.width - sw - imageOffset - 2 - 5 - 3;
  471.                ++r.y;
  472.                g.drawImage(im, r.x, r.y, this);
  473.                --r.y;
  474.                r.x = origX + r.width - sw - 5 - 3;
  475.             } else {
  476.                imageOffset = 0;
  477.                if (sw > r.width - 10) {
  478.                   r.x += 5;
  479.                } else {
  480.                   r.x = origX + r.width - sw - 5 - 3;
  481.                }
  482.             }
  483.       }
  484.  
  485.       hints.setForeground(g);
  486.       r.width = r.width + origX - r.x - 5;
  487.       this.startX = r.x;
  488.       this.drawText(data, g, r, fm, hints);
  489.       r.width = origWidth;
  490.       if (this.selected && this.keyPressedYet) {
  491.          int cpos = 0;
  492.          if (data.toString().length() > 0) {
  493.             cpos = fm.stringWidth(data.subString(this.toLeftOfCell, this.cursorPos));
  494.          }
  495.  
  496.          g.drawLine(r.x + cpos, r.y + 2, r.x + cpos, r.y + fm.getHeight());
  497.       }
  498.  
  499.       r.x = origX;
  500.       hints.drawBoundary(g);
  501.    }
  502.  
  503.    protected String chopString(Data data, Rectangle r, FontMetrics fm) {
  504.       String text = data.toString();
  505.       int w = this.view.getColumnWidth(this.coords.col);
  506.       this.chopIndex = 1;
  507.       if (text.length() == 0) {
  508.          return text;
  509.       } else {
  510.          this.setOffset(text, r, fm);
  511.          if (this.offset == 0) {
  512.             this.toLeftOfCell = 0;
  513.          } else {
  514.             while(this.toLeftOfCell < text.length()) {
  515.                int left = fm.stringWidth(text.substring(0, this.toLeftOfCell));
  516.                if (left >= this.offset + 5) {
  517.                   --this.toLeftOfCell;
  518.                   break;
  519.                }
  520.  
  521.                ++this.toLeftOfCell;
  522.             }
  523.  
  524.             this.toLeftOfCell -= this.toLeftOfCell < text.length() ? 0 : 1;
  525.             text = text.substring(this.toLeftOfCell, text.length());
  526.          }
  527.  
  528.          String t;
  529.          do {
  530.             t = text.substring(0, this.chopIndex);
  531.          } while(fm.stringWidth(t) < w - 10 && this.chopIndex++ < text.length());
  532.  
  533.          return text.substring(0, --this.chopIndex);
  534.       }
  535.    }
  536.  
  537.    protected void drawText(Data data, Graphics g, Rectangle r, FontMetrics fm, CellHints hints) {
  538.       String text = this.chopString(data, r, fm);
  539.       if (this.selected && !this.keyPressedYet) {
  540.          hints.setForeground(g);
  541.          g.fillRect(r.x - 1, r.y + 3, fm.stringWidth(text.toString()) + 4, fm.getHeight() - 1);
  542.          hints.setBackground(g);
  543.          g.drawString(text, r.x, r.y + fm.getAscent() + 2);
  544.       } else if (this.selected && !this.selectionMade) {
  545.          g.drawString(text, r.x, r.y + fm.getAscent() + 2);
  546.       } else if (this.selected && this.selectionMade) {
  547.          int hlLeft = Math.min(this.hlFirst, this.hlLast);
  548.          int hlRight = Math.max(this.hlFirst, this.hlLast);
  549.          hlRight = Math.min(hlRight, this.chopIndex);
  550.          if (this.toLeftOfCell != 0) {
  551.             hlLeft = Math.max(this.hlFirst, this.toLeftOfCell);
  552.          }
  553.  
  554.          String t = text.substring(0, hlLeft);
  555.          g.drawString(t, r.x, r.y + fm.getAscent() + 2);
  556.          int pixelHLStart = fm.stringWidth(t) + r.x - this.offset;
  557.          t = text.substring(hlLeft, hlRight);
  558.          int pixelHLStop = fm.stringWidth(t) + pixelHLStart;
  559.          hints.setForeground(g);
  560.          g.fillRect(pixelHLStart, r.y + 2, pixelHLStop - pixelHLStart, fm.getHeight() - 1);
  561.          hints.setBackground(g);
  562.          g.drawString(t, pixelHLStart, r.y + fm.getAscent() + 2);
  563.          hints.setForeground(g);
  564.          t = text.substring(hlRight, text.length());
  565.          g.drawString(t, pixelHLStop, r.y + fm.getAscent() + 2);
  566.       } else {
  567.          g.drawString(text, r.x, r.y + fm.getAscent() + 2);
  568.       }
  569.    }
  570.  
  571.    void setOffset(String text, Rectangle r, FontMetrics fm) {
  572.       String sub = text.substring(0, this.cursorPos);
  573.       int toCursor = fm.stringWidth(sub);
  574.       int fudge = 3;
  575.       if (!this.selected) {
  576.          this.offset = 0;
  577.       } else if (toCursor > r.width - fudge) {
  578.          this.offset = -r.width + toCursor + fudge;
  579.       } else {
  580.          this.offset = 0;
  581.       }
  582.    }
  583.  
  584.    int textLeft(int txtWidth, Rectangle r) {
  585.       switch (this.view.getCellAlignment(this)) {
  586.          case 0:
  587.          default:
  588.             return r.x + 5;
  589.          case 1:
  590.             if (txtWidth > r.width) {
  591.                return r.x;
  592.             }
  593.  
  594.             return r.x + (r.width - txtWidth) / 2;
  595.          case 2:
  596.             return txtWidth > r.width ? r.x + 5 : r.x + r.width - txtWidth - 5;
  597.       }
  598.    }
  599.  
  600.    public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h) {
  601.       if ((flags & 192) != 0) {
  602.          return false;
  603.       } else if ((flags & 32) != 0) {
  604.          this.view.redraw(true);
  605.          return false;
  606.       } else {
  607.          return true;
  608.       }
  609.    }
  610.  
  611.    public String toString() {
  612.       try {
  613.          return this.readData().toString();
  614.       } catch (DataNotAvailable var1) {
  615.          return "ERROR getting data";
  616.       }
  617.    }
  618.  
  619.    public String stats() {
  620.       try {
  621.          return "BasicCell: row=" + this.coords.row + " col=" + this.coords.col + " text=" + this.readData().toString();
  622.       } catch (DataNotAvailable var1) {
  623.          return "BasicCell: row=" + this.coords.row + " col=" + this.coords.col + " could not retrieve data";
  624.       }
  625.    }
  626. }
  627.